package com.users.rn.rncommon.ui;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.alibaba.android.arouter.launcher.ARouter;
import com.users.rn.common.cmbroadcast.RNKITTools;
import com.users.rn.common.plugin.PluginHelper;
import com.users.rn.rncommon.R;
import com.users.rn.rncommon.manager.ALHReactDebugHostManager;
import com.users.rn.rncommon.manager.ALHReactEnvManager;
import com.users.rn.rncommon.manager.ALHReactNativeHost;
import com.users.rn.rncommon.model.PluginInfo;
import com.users.rn.rncommon.plugin.PluginInformation;
import com.users.rn.rncommon.plugin.ReactLoadUtils;
import com.users.rn.rncommon.util.RNDebugUtils;
import com.users.rn.rncommon.util.RNPageUtil;
import com.users.rn.rncommon.util.ReactConst;
import com.users.rn.rncommon.util.ReactUtils;
import com.ylkj.libcommon.constants.ARouterConstants;
import com.examination.mlib.interfaceapi.BaiduApi;
import com.ylkj.libcommon.utils.ClickUtils;
import com.ylkj.libcommon.utils.ALog;
import com.examination.mlib.view.SuspendedBallView;

import org.json.JSONException;
import org.json.JSONObject;

import static com.users.rn.rncommon.util.ReactConst.INTENT_KEY_COMPONENT_NAME;
import static com.users.rn.rncommon.util.ReactConst.INTENT_KEY_MODULE_ID;
import static com.users.rn.rncommon.util.ReactConst.INTENT_KEY_PLUGIN_ID;

public class RNActivity extends ReactBaseActivity {

    private String componentNameString;
    private BaiduApi baiduApi;
    private SuspendedBallView ballView;

    public static <T extends RNActivity> Intent getIntent(Context context, Class<T> clazz, String pluginId, String moduleId, String componentName, Bundle params) {
        Intent intent = new Intent(context, clazz);
        intent.putExtra(INTENT_KEY_PLUGIN_ID, pluginId);
        intent.putExtra(INTENT_KEY_MODULE_ID, moduleId);
        intent.putExtra(INTENT_KEY_COMPONENT_NAME, componentName);
        if (params == null) {
            params = new Bundle();
        }
        params.putString(ReactConst.INTENT_KEY_PAGE_TAG, RNPageUtil.createPageTag(pluginId, componentName));
        intent.putExtra(ReactConst.INTENT_KEY_PARAMS, params);
        return intent;
    }

    //继续当前debug状态的plugin，如果跳转的是其他plugin，则走本地
    private String debugPluginId;
    private PluginInfo pluginInfo;

    private PluginInfo initPluginInfo(Intent intent) {
        if (intent == null) {
            return null;
        }
        String pluginId = intent.getStringExtra(INTENT_KEY_PLUGIN_ID);
        String moduleId = intent.getStringExtra(INTENT_KEY_MODULE_ID);
        String componentName = intent.getStringExtra(INTENT_KEY_COMPONENT_NAME);
        Bundle params = intent.getBundleExtra(ReactConst.INTENT_KEY_PARAMS);
        debugPluginId = ReactUtils.getDebugPluginId(this, pluginId) ? pluginId : null;
        boolean eventFlag = ReactUtils.getEventFlag(this);
        //是否是拆包
        boolean isUnpack = PluginHelper.INSTANCE.pluginIsPartial(pluginId);
        PluginInfo info = new PluginInfo(pluginId, moduleId, componentName, params, isUnpack, eventFlag);
        //sdcard bundle version
        Long pluginVersion = PluginHelper.INSTANCE.getPluginVersion(pluginId);
        String pluginDownloadPath = PluginInformation.getPluginPath(pluginId, pluginVersion);//PluginManager.getPluginDownloadPath(this, pluginId);
        info.setBundlePathAndVersion(pluginDownloadPath, pluginVersion);
        ReactUtils.log(info.toString());
        return info;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityManagerUtils.addActivities(this);
        ARouter.getInstance().inject(this);
        baiduApi = (BaiduApi) ARouter.getInstance().build(ARouterConstants.BaiduImpl).navigation();
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return;
        }
        pluginInfo = initPluginInfo(intent);
        componentNameString = pluginInfo.getComponentName();
        if (componentNameString.equals("MyActivityDetails")
                || componentNameString.equals("MyActivityList")
                || componentNameString.equals("ImChating")
        ) {
//        键盘顶掉布局
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        } else {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        }

        if (isDebugEnv()) {
            ReactUtils.log("loadBundle debug");
            setDebugIpToSp();
            ALHReactNativeHost debugHost = ALHReactDebugHostManager.getInstance().get(debugPluginId);
            super.onDelegateCreate(debugHost, pluginInfo);

            loadApp();
            return;
        }
        ALHReactNativeHost host = ALHReactEnvManager.getInstance().getReactNativeHost(pluginInfo);
        if (host == null) {
            ReactUtils.logError("host == null, bundle文件找不到");
//        ReactUtils.eventBizBundle(mActivity, mActivitySavedInfo, "bundle文件找不到");
            finish();
            return;
        }
        host.readyForReactNativeHostListener(pluginInfo, onLoadScriptListener);
        //onDelegateCreate方法是将host设置，这个host中的react context是提前预热的，必须在loadBundle方法之前
        super.onDelegateCreate(host, pluginInfo);
        ReactLoadUtils.loadBundle(getReactHost(), onLoadScriptListener, pluginInfo);
//        getReactNativeHost().getReactInstanceManager()


    }

    private boolean isDebugEnv() {
        return !TextUtils.isEmpty(debugPluginId);
    }

    private ReactLoadUtils.OnLoadScriptListener onLoadScriptListener = (responseStatus, msg) -> {
        if (responseStatus == ReactConst.LOAD_BUNDLE_SUCCESS) {
            removeOnLoadScriptListener();
            loadApp();
        } else if (responseStatus == ReactConst.LOAD_ASSETS_BIZ_BUNDLE_FAILED) {
            removeOnLoadScriptListener();
            //如果记载的biz bundle在assets下都找不到，可能是低版本主客调用了高版本才有的rn包
            finish();
        } else {
            if (isDebugEnv()) {
                return;
            }
            ReactUtils.eventBizBundle(this, pluginInfo, msg);
        }
    };


    protected void removeOnLoadScriptListener() {
        ALHReactNativeHost host = getReactHost();
        if (host != null) {
            host.removeListener(onLoadScriptListener);
        }
    }

    @Override
    protected void onStart() {
        baiduApi.onPageStart(this, componentNameString);
        super.onStart();
    }

    @Override
    protected void onResume() {
        baiduApi.onResume(this);
        super.onResume();
        if (isDebugEnv()) {
            setDebugIpToSp();
        }
    }

    @Override
    protected void onPause() {
        baiduApi.onPause(this);
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        ActivityManagerUtils.removeActivities(this);
        baiduApi.onPageEnd(this, componentNameString);
        super.onDestroy();
        removeOnLoadScriptListener();
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("tag", "refresh");
            jsonObject.put("pageName", componentNameString);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        RNKITTools.INSTANCE.sendBroadcast(this, "ReceiveRefreshKey", jsonObject.toString());
        if (getReactHost() != null) {
            getReactHost().removeComponent(pluginInfo.getPluginId(), pluginInfo.getComponentName());
        }
    }

    private void setDebugIpToSp() {
        PreferenceManager.getDefaultSharedPreferences(this)
                .edit()
                .putString(ReactConst.DEBUG_IP, RNDebugUtils.getDebugIp(this, debugPluginId))
                .apply();
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
//        HashMap<String, Object> hashMap = new HashMap<>();
//        hashMap.put("tag", "refresh");
//        hashMap.put("pageName", componentNameString);
//        String s = new Gson().toJson(hashMap);
//        RNKITTools.INSTANCE.sendBroadcast(this, "ReceiveRefreshKey", s);
        return super.onKeyDown(keyCode, event);

    }

    public void showPopBall() {
        try {
            if (ballView == null) {
                FrameLayout frameLayout = (FrameLayout) LayoutInflater.from(RNActivity.this).inflate(R.layout.layout_suspended_ball, ((FrameLayout) getWindow().getDecorView().findViewById(android.R.id.content)));
                ballView = frameLayout.findViewById(R.id.suspended_ball_view);
            }
            ballView.isHiddenSuspendedBallView(2, new SuspendedBallView.HiddenCallBack() {
                @Override
                public void hidden(boolean hidden) {
                    if (hidden) {
                        ballView.setVisibility(View.GONE);
                    } else {
                        ballView.setVisibility(View.VISIBLE);
                    }
                }

                @Override
                public void setIcon(String iconUrl) {
                    if (iconUrl != null) {
                        ballView.setGifIcon(iconUrl);
                    } else {
                        ballView.setGifIcon(R.drawable.icon_default_square);
                    }
                }

                @Override
                public void getUrl(String url) {
                    ballView.setActivityUrl(url);
                }
            });

            ClickUtils.setFastOnClickListener(ballView, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ballView.show();
                }
            });
        } catch (Throwable throwable) {
            ALog.e("okhttp:" ,"showPopBall error: " + throwable.getMessage());
            throwable.printStackTrace();
        }

    }
}